package top.rish.converter.info;

import lombok.Data;
import top.rish.converter.utils.ObjKit;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;

@Data
public class AnnoWrap {
    // 当前注解的注解
    public List<AnnoWrap> annoList = ObjKit.newEpmtyList(AnnoWrap.class);

    // 当前注解信息
    public MetaMap annoValueMap = new MetaMap();

    // 当前注解类型
    public Class<? extends Annotation> annoClass;


    public static List<AnnoWrap> of(Object o) {

        return  new ArrayList<>();
    }

    private static final String JAVA_ANNO_PACKAGE ="java.lang.annotation.";

    public static void rejAnnotation(AnnoWrap wrap,Annotation a){
        String n = a.annotationType().getName();
        Annotation[] pa = a.annotationType().getAnnotations();
        if( !n.startsWith(JAVA_ANNO_PACKAGE) && ObjKit.isNotEmpty(pa)){
            wrap.setAnnoList(Arrays.stream(pa)
                .filter(ix->!ix.annotationType().getName().startsWith(JAVA_ANNO_PACKAGE))
                    .map(aa->{
                AnnoWrap w = wrapByAnnotation(aa);
                rejAnnotation(w,aa);
                return  w;
            }).collect(Collectors.toList()));
        }
    }

    private static final Map<Field,List<AnnoWrap>> CACHE = new HashMap<>();

    public static List<AnnoWrap> ofField(Field field) {
        if(CACHE.containsKey(field)){
            return CACHE.get(field);
        }
        Annotation[] annotations = field.getAnnotations();
        List<AnnoWrap> aw =   Arrays.stream(annotations).map(annotation -> {
            AnnoWrap wrap = wrapByAnnotation(annotation);
            rejAnnotation(wrap,annotation);
            return  wrap;
        }).collect(Collectors.toList());
        CACHE.put(field,aw);
        return aw;
    }

    public static List<AnnoWrap> ofEntity(Object entity) {

        return  new ArrayList<>();
    }



    public static  AnnoWrap  wrapByAnnotation(Annotation annotation) {
        AnnoWrap wrap = new AnnoWrap();
        wrap.setAnnoClass(annotation.annotationType());
        wrap.setAnnoValueMap(MetaMap.ofAnnotation(annotation));
        return  wrap;
    }
}
